Le TD a commencé par un petit contrôle... que nous avons ensuite (partiellement) corrigé.

Correction de l'exercice mystère.

Rappel du sujet initial :


In [1]:
def mystere(unparametre)
    unevariable = True
    uneautrevariable = 0
    while unevariable:
        truc = unparametre // 10
        uneautrevariable+=1
        if truc = 0:
        print("truc 0")
        if truc > 0:
            unparametre = truc
        else:
            unevariable = False
    return uneautrevariable

print(mystere(1))
print(mystere(22))
print(mystere(4444))


  File "<ipython-input-1-7234389ae404>", line 1
    def mystere(unparametre)
                            ^
SyntaxError: invalid syntax

1 : Correction des trois erreurs de syntaxe


In [2]:
def mystere(unparametre): # il manquait les deux points ici...
    unevariable = True
    uneautrevariable = 0
    while unevariable:
        truc = unparametre // 10
        uneautrevariable+=1
        if truc == 0: # la condition du if doit être une formule booléenne... il fallait donc un == et non un =
            print("truc 0") # Il y avait un problème d'in
        if truc > 0:
            unparametre = truc
        else:
            unevariable = False
    return uneautrevariable

print(mystere(1))
print(mystere(22))
print(mystere(4444))


truc 0
1
truc 0
2
truc 0
4

2 : Que fait le programme ?

Le programme retourne le nombre de chiffres dans l'écriture en base 10 d'un nombre passé en paramètre. Le premier if fait un print qui ne sert à rien.

3 : Quelles valeurs choisir pour le test

Les valeurs aux limites des conditions : par exemple, 0, 10 ou 100... Les valeurs négatives. Les nombres flotants.

Exercice du damier :

L'objectif de cet exercice est d'afficher un damier de M*N cases, chaque case étant soit vide (caractère espace) soit dessinée par un ensemble de lettre.

Chaque case du damier aura pour dimension 2M*N (cf. plus bas pour l'explication du 2M).

Par exemple, si l'on demande l'affichage d'un damier de 5*4, on aura 20 cases en tout, et le damier fera 5 colonnes par 4 lignes. Chaque case du damier fera quant à elle 10 caractères de large, et 4 caractères de haut.

Les cases pleines sont dessinées avec deux caractères passés en paramètres de la méthode. On affiche d'abord M fois le premier caractère, puis M fois le second. La largeur d'une case est donc de 2M. On doit répéter l'opération N fois, car la case doit avoir une hauteur de N. Les cases vides fonctionnent selon le même principe, sauf qu'au lieu d'afficher des caractères passés en paramètres, on affiche des espaces.

L'une des principales difficultés, outre les aspects algorithmiques, est que l'affichage doit se faire ligne par ligne (et non case par case), et qu'il va donc nous falloir décomposer le problème en fonction de cette contrainte.

Cet exercice est artificiellement difficile. Il a pour but de vous apprendre à décomposer un problème compliqué en plusieurs étapes "simples", et de vous faire travailler le concept de boucles imbriquées.

Nous allons donc le corriger par étapes.

Étape 1.

Tout d'abord, nous allons écrire et tester le code qui permet d'afficher une ligne (en faisant le choix arbitraire que la première case de la ligne est une case pleine.


In [3]:
def afficher_damier(m, n, c, d):
    '''
    :entree m: nombre de cases en largeur dans le damier
    :entree n: nombre de cases en hauteur dans le damier
    :entree c: premier caractère choisi pour l'affichage
    :entree d: deuxieme caractère choisi pour l'affichage
    :pre-cond: m et n sont des entiers strictement positifs
    :pre-cond: c et d sont des chaînes de caractères de longueur 1 (autrement dit, des caractères)
    :post-cond: un damier de m*n cases est affiché à l'écran, en utilisant les caractères c et d, comme dans l'exemple ci-dessous :
    afficher_damier(2,3, "n", "z") 
    nnzz
    nnzz
    nnzz
        nnzz
        nnzz
        nnzz
    nnzz
    nnzz
    '''   
    case = 1 # On utilise une variable pour repérer sur quelle case on est.
    chaine = "" # On utilise une variable pour stocker la chaine à afficher et on s'occupera de l'affichage de cette chaine à chaque fin de ligne
    for compteur in range(m): # On fait une boucle pour construire une ligne entière de cases
        if case % 2 == 0: # Si on est sur une case paire, on ajoute à la chaine le nombre d'espaces (2M)
            chaine = chaine + (2*m* " ")
        else: # Sinon (i.e. la case est impaire), on ajoute à la chaine M fois le premier caractère, puis M fois le second. 
            chaine = chaine + (m*c + m*d)
        case += 1 # Quand on a fini d'écrire une case, on passe à la case suivante
    print(chaine) # Quand on a fini d'écrire une ligne entière, on l'affiche.


afficher_damier(3, 4, "-", "6") # Hop, et on n'oublie pas de tester notre travail.


---666      ---666

Étape 2. Bien. Maintenant que l'on affiche une ligne correctement, on va s'occuper d'afficher toutes les lignes nécessaires à l'affichage de la première rangée de cases de notre damier. On reprend notre code précédent, et on le modifie un peu... Dans le code ci-dessous, seules les lignes modifiées ont été commentées.


In [4]:
def afficher_damier(m, n, c, d):
    '''
    idem
    '''   
    for compteur_ligne in range(n): # On ajoute juste une boucle pour itérer sur la hauteur que doit faire une case... 
        case = 1 
        chaine = "" 
        for compteur in range(m): 
            if case % 2 == 0: 
                chaine = chaine + (2*m* " ")
            else: 
                chaine = chaine + (m*c + m*d)
            case += 1 
        print(chaine) 

afficher_damier(3, 4, "-", "6") # Hop, et on n'oublie pas de tester notre travail.


---666      ---666
---666      ---666
---666      ---666
---666      ---666

Étape 3. Parfait. Nous avons réalisé la première ligne de cases de notre damier. Maintenant, il s'agit de répéter le processus pour le reste du damier... mais il nous faut trouver une astuce pour gérer le décalage que doivent avoir les cases d'une ligne sur l'autre. Ici, on utilise l'observation suivante. On numérote les cases de 1 à m, et les lignes de 1 à n. On a fait le choix que la case 1 de la ligne 1 était une case pleine. Ainsi, la case 2 de la ligne 1 est une case vide, mais la case 1 de la ligne 2 est vide aussi. En généralisant, on observe assez vite que lorsque la somme du rang de la case et du numéro de ligne est paire, la case est pleine, et dans l'autre cas, la case est vide. C'est cette observation que l'on va utiliser dans le code suivant.


In [5]:
def afficher_damier(m, n, c, d):
    '''
    idem
    '''   
    ligne = 1 # On introduit un compteur pour savoir quelle ligne on est en train de traiter 
    for compteur_lignes_damier in range(n): # On itère sur les lignes
        for compteur_ligne in range(n): 
            case = 1 
            chaine = "" 
            for compteur in range(m): 
                if (case + ligne) % 2 != 0: # On modifie la condition qui nous permet de savoir ce que l'on doit écrire dans la case...  
                    chaine = chaine + (2*m* " ")
                else: 
                    chaine = chaine + (m*c + m*d)
                case += 1 
            print(chaine) 
        ligne += 1 # Quand on a fini d'écrire une ligne complète, on pense à incrémenter notre compteur de ligne...

afficher_damier(3, 4, "-", "6") # Hop, et on n'oublie pas de tester notre travail.
afficher_damier(6, 2, "g", "!")


---666      ---666
---666      ---666
---666      ---666
---666      ---666
      ---666      
      ---666      
      ---666      
      ---666      
---666      ---666
---666      ---666
---666      ---666
---666      ---666
      ---666      
      ---666      
      ---666      
      ---666      
gggggg!!!!!!            gggggg!!!!!!            gggggg!!!!!!            
gggggg!!!!!!            gggggg!!!!!!            gggggg!!!!!!            
            gggggg!!!!!!            gggggg!!!!!!            gggggg!!!!!!
            gggggg!!!!!!            gggggg!!!!!!            gggggg!!!!!!

In [ ]: